package de.fhd.pms.ctrl;

import java.util.Date;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import de.fhd.pms.dao.AutomobilDao;
import de.fhd.pms.dao.AutomobilDeleteException;
import de.fhd.pms.dao.StandortDao;
import de.fhd.pms.model.Automobil;

// DEFINITON DER KLASSE ALS CONTROLLER

/**
 * Controller von Automobil.
 * <p>
 * Der AutomobilController übernimmt die Ablaufsteuerung für das Handling von Automobilen (z. B. Userinputs).
 * 
 * @author Martin Schmid
 * @author Florian Schachner
 */
@Controller
public class AutomobilController {

	private static Logger log = Logger.getLogger(AutomobilController.class);

	// Schritt 2: Definition einer DAO-Instanz vom Typ der Klasse AutomobilDao
	private AutomobilDao automobilDao = null;
	private StandortDao standortDao = null;

	// Schritt 3: setAutomobilDao-Methode:
	// Hier greift das IoC-Prinzip (Hollywood-Prinzip):
	// "Ich erwarte, das mir jemand ein Dao-Objekt mitgibt (in application-context.xml definiert)"


	public void setAutomobilDao(AutomobilDao automobilDao) {
		this.automobilDao = automobilDao;
	}

	public void setStandortDao(StandortDao standortDao) {
		this.standortDao = standortDao;
	}

	/**
	 * Edit-Methode von AutomobilController.
	 * <p>
	 * Hierbei wird es ermöglicht, bestehende Automobile abzuändern bzw. zu
	 * editieren oder neue Automobile in den Fuhrpark aufzunehmen. 
	 * Reagiert auf einen HTTP-Request '/EditAutomobil.html'.
	 * 
	 * @param id - Integer
	 * @return Gibt ein Objekt vom Typ {@link ModelAndView} ("EditAutomobil") zurück.
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	@RequestMapping(value = "/EditAutomobil.html", method = RequestMethod.GET)
	public ModelAndView edit(@RequestParam(required = false) Integer id) {
		ModelAndView mv = new ModelAndView();
		if (id == null) {
			mv.addObject(new Automobil());
		} else {
			mv.addObject(automobilDao.findById(id));
		}

		if (id == null) {
			mv.addObject("title", "Automobil anlegen");
			mv.addObject("message", "Mithilfe dieses Eingabeformulars können neue Automobile in den Fuhrpark des CarSharing-Projekts aufgenommen werden.");
			mv.addObject("standort", standortDao.findAll());
			mv.addObject("standorte", standortDao.findAll());
			mv.addObject("edit", false);
		} else {
			mv.addObject("title", "Automobil bearbeiten");
			mv.addObject("message",	"Mithilfe dieses Eingabeformulars können Daten von bestehenden Automobilen geändert werden.");
			mv.addObject("standort", standortDao.findById(automobilDao.findById(id).getAktuellerstandort()));
			mv.addObject("standorte", standortDao.findAll());
			mv.addObject("edit", true);
		}
		mv.setViewName("editAutomobil");
		return mv;
	}

	/**
	 * Save-Methode von AutomobilController speichert die Automobilinstanz in der Datenbank.
	 * <p>
	 * Hierbei wird es ermöglicht, ein Automobil in der Datenbank zu speichern.
	 * Reagiert auf einen HTTP-Request '/SaveAutomobil.html'.
	 * 
	 * @param automobil - Ein Objekt der Klasse {@link Automobil}
	 * @param model - 
	 * @return Einen Redirect mit dem Befehl 'AlleAutomobile.html'
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	@RequestMapping(value = "/SaveAutomobil.html", method = RequestMethod.POST)
	public String save(Automobil automobil, Model model) {
		log.info("AUTOMOBILCONTROLLER: SaveAutomobil.html");

		if (automobil.getCreated() == null) {
			automobil.setCreated(new Date());
		}
		Automobil result = automobilDao.save(automobil);
		// Setzen der ID, welche durch die Datenbank vergeben wurde
		if (automobil.getId() == null) {
			automobil.setId(result.getId());
		}
		model.addAttribute("statusMessageKey", "automobil.form.msg.success");
		return "redirect:AlleAutomobile.html";
	}

	/**
	 * FindAll-Methode von AutomobilController.
	 * <p>
	 * Hierbei wird es ermöglicht, alle im Fuhrpark befindlichen Automobile in
	 * der Datenbank auszulesen. Diese Methode reagiert auf den Befehl
	 * '/AlleAutomobile.html'. Sie liefert alle Automobile des Fuhrparks aus der
	 * Datenbank zurück. Alle gefundenen Automobile werden dem
	 * ModelAndView-Objekt hinzugefügt. Abschließend wird die View mit Namen
	 * "listAutomobile" aufgerufen.
	 * 
	 * @return Gibt ein Objekt vom Typ {@link ModelAndView} ("listAutomobile") zurück.
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	@RequestMapping(value = "/AlleAutomobile.html", method = RequestMethod.GET)
	public ModelAndView findAll() {
		log.info("AUTOMOBILCONTROLLER: AlleAutomobile.html");
		ModelAndView mv = new ModelAndView();
		mv.addObject("title", "Alle Automobile im CarSharing-Projekt");
		mv.addObject("message", "Hier befinden sich alle Automobile die am CarSharing-Projekt teilnehmen");
		mv.addObject("automobil", automobilDao.findAll());
		mv.addObject("edit", true);
		mv.setViewName("listAutomobile");
		return mv;
	}

	/**
	 * FreieAutomobile-Methode von AutomobilController.
	 * <p>
	 * Hierbei wird es ermöglicht, alle aktuell freien Automobile aus der
	 * Datenbank auszulesen. Diese Methode reagiert auf den Befehl
	 * '/FreieAutomobile'. Alle gefundenen Automobile werden dem ModelAndView-Objekt
	 * hinzugefügt. Abschließend wird die View mit Namen "listAutomobile" aufgerufen.
	 * 
	 * @return Gibt ein Objekt vom Typ {@link ModelAndView} ("listAutomobile") zurück.
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	@RequestMapping(value = "/FreieAutomobile.html", method = RequestMethod.GET)
	public ModelAndView freieAutomobile() {
		ModelAndView mv = new ModelAndView();
		mv.addObject("title", "Fahrt beginnen");

		if (automobilDao.findFreie().isEmpty()==true) {
			mv.addObject("message",	"Der Eintrag einer neuen Fahrt ist leider nicht möglich, da aktuell keine Automobile zur Verfügung stehen.");
			mv.setViewName("displayNoFahrtPossible");
		} else {
			mv.addObject("message",	"Folgende Automobile sind für eine Fahrt verfügbar. Wählen Sie ein Fahrzeug aus:");
			mv.addObject("automobil", automobilDao.findFreie());
			mv.addObject("edit", false);
			mv.setViewName("listAutomobile");
		}

		return mv;
	}
	
	
	
	/**
	 * Delete-Methode von AutomobilController.
	 * <p>
	 * Hierbei wird es ermöglicht, ein spezifisches Automobil aus der Datenbank
	 * zu löschen. Diese Methode reagiert auf den Befehl '/LoescheAutomobil.html'. 
	 * Abschließend wird die View mit Namen "AlleAutomobile" bzw. aufgerufen.
	 * 
	 * @param automobil - Ein Objekt der Klasse {@link Automobil}
	 * @return Einen Redirect mit dem Befehl 'AlleAutomobile.html'
	 * @author Martin Schmid
	 * @author Florian Schachner
	 */
	@RequestMapping(value = "/LoescheAutomobil.html", method = RequestMethod.GET)
	public ModelAndView delete(Automobil automobil) {
		log.info("AUTOMOBILCONTROLLER: LoescheAutomobil.html");
		
		try {
			automobilDao.delete(automobil);
			return new ModelAndView("redirect:AlleAutomobile.html");
		} catch (AutomobilDeleteException e) {
			ModelAndView mv = new ModelAndView("error");
			mv.addObject("message", e.getMessage());
			return mv;
		}
	}

}
